﻿using DocTranslator.Models;
using DocTranslator.Services.Interfaces;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

namespace DocTranslator.Services
{
    public class DeepSeekTranslationService : ITranslationService
    {
        private readonly string _apiKey;
        private readonly string _apiUrl;
        private readonly HttpClient _httpClient;
        private readonly ILogger<DeepSeekTranslationService> _logger;

        public DeepSeekTranslationService(
            IConfiguration configuration, 
            IHttpClientFactory httpClientFactory,
            ILogger<DeepSeekTranslationService> logger)
        {
            _apiKey = configuration["DeepSeek:ApiKey"];
            _apiUrl = configuration["DeepSeek:ApiUrl"];
            _logger = logger;

            //配置请求头
            _httpClient = httpClientFactory.CreateClient();
            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }

        //翻译
        public async Task<string> TranslateAsync(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return text;

            // 构建请求数据
            var requestData = new
            {
                model = "deepseek-chat",
                messages = new[]
                {
                    new
                    {
                        role = "system",
                        content = "你是一个专业的翻译专家，专注于将文本准确自然地翻译成英文。请保留专业术语和格式，只返回翻译结果不要添加任何额外内容。"
                    },
                    new
                    {
                        role = "user",
                        content = $"请翻译以下内容: {text}"
                    }
                },
                //设置大模型采样温度，控制生成文本的随机性，值越高，生成的文本越随机，值越低，生成的文本越确定
                //这里需要的是翻译，要求准确性高，所以设置较低的温度，要求DeepSeek严谨翻译
                temperature = 0.3,
                max_tokens = 4000
            };

            var json = JsonSerializer.Serialize(requestData);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            int retryCount = 0;
            int maxRetries = 3;
            while (retryCount < maxRetries)
            {
                try
                {
                    // 发送请求
                    var response = await _httpClient.PostAsync(_apiUrl, content);

                    //处理失败响应
                    if (!response.IsSuccessStatusCode)
                    {
                        var errorContent = await response.Content.ReadAsStringAsync();
                        _logger.LogError($"DeepSeek API 请求失败: {response.StatusCode} - {errorContent}");


                        // 不需要重试的错误码
                        var statusCode = (int)response.StatusCode;
                        if (statusCode == 400 || statusCode == 401 || statusCode == 402 || statusCode == 422)
                        {
                            _logger.LogError($"客户端错误 ({statusCode})，{errorContent}");
                            return text;
                        }else{
                            retryCount++;
                            if (retryCount > maxRetries)
                                throw new Exception("达到最大重试次数");

                            // 指数退避策略，双倍等待时间
                            int delay = (int)Math.Pow(2, retryCount) * 1000;
                            //非阻塞睡觉
                            await Task.Delay(delay);
                            continue;
                        }

                        throw new HttpRequestException($"DeepSeek API 请求失败: {response.StatusCode}");
                    }

                    // 解析响应
                    var responseJson = await response.Content.ReadAsStringAsync();
                    var responseObject = JsonSerializer.Deserialize<DeepSeekApiResponse>(responseJson);

                    // 返回翻译结果
                    return responseObject?.choices?[0]?.message?.content?.Trim() ?? text;
                }   
                catch (Exception ex)
                {
                    _logger.LogError(ex, "DeepSeek 翻译失败");
                    retryCount++;
                    if (retryCount >= maxRetries)
                    {
                        _logger.LogError("达到最大重试次数，返回原文");
                        return text;
                    }
                    int delay = (int)Math.Pow(2, retryCount) * 1000;
                    await Task.Delay(delay);
                }
            }
            // 所有重试都失败，返回原文
            return text; 
        }
    }
}
